package org.jeecg.modules.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.jeecg.common.modules.dic.entity.DicBeGoodAt;
import org.jeecg.common.modules.dic.service.IDicBeGoodAtService;
import org.jeecg.common.modules.doctor.entity.*;
import org.jeecg.common.modules.doctor.service.*;
import org.jeecg.common.modules.doctor.vo.DoctorRegisterRecordSysListVo;
import org.jeecg.common.modules.makeAppointment.entity.MakeAppointment;
import org.jeecg.common.modules.makeAppointment.entity.MakeAppointmentInfo;
import org.jeecg.common.modules.makeAppointment.service.IMakeAppointmentInfoService;
import org.jeecg.common.modules.makeAppointment.service.IMakeAppointmentService;
import org.jeecg.common.modules.makeAppointment.service.impl.MakeAppointmentServiceImpl;
import org.jeecg.common.modules.order.entity.OrderInfo;
import org.jeecg.common.modules.order.entity.PayOrder;
import org.jeecg.common.modules.order.service.IOrderInfoLogService;
import org.jeecg.common.modules.order.service.IOrderInfoService;
import org.jeecg.common.modules.order.service.IPayOrderService;
import org.jeecg.common.modules.patient.entity.Patient;
import org.jeecg.common.modules.patientMedicalRecords.entity.PatientMedicalRecords;
import org.jeecg.common.modules.patientMedicalRecords.service.IPatientMedicalRecordsService;
import org.jeecg.common.modules.register.entity.RegisterPatient;
import org.jeecg.common.modules.register.entity.RegisterPayOrder;
import org.jeecg.common.modules.register.service.IRegisterPatientService;
import org.jeecg.common.modules.register.service.IRegisterPayOrderService;
import org.jeecg.common.modules.roomScord.entity.RoomScord;
import org.jeecg.common.modules.roomScord.service.IRoomScordService;
import org.jeecg.common.modules.wx.entity.WxUserinfo;
import org.jeecg.common.modules.wx.service.IWxUserinfoService;
import org.jeecg.common.util.*;
import org.jeecg.common.util.enums.*;
import org.jeecg.common.util.result.Result;
import org.jeecg.common.util.result.ResultMapper;
import org.jeecg.common.util.wx.WeixinUtil;
import org.jeecg.common.util.wx.WxPayUtil;
import org.jeecg.modules.config.CustomProperties;
import org.jeecg.modules.vo.request.PrePayOrderRequestVo;
import org.jeecg.modules.vo.respone.PrePayOrderResponseVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.weixin4j.WeixinException;
import org.weixin4j.model.pay.PayNotifyResult;
import org.weixin4j.model.pay.UnifiedOrder;
import org.weixin4j.model.pay.UnifiedOrderResult;
import org.weixin4j.model.pay.WCPay;
import org.weixin4j.spring.WeixinTemplate;
import org.weixin4j.util.PayUtil;
import org.weixin4j.util.SignUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.jeecg.common.util.constants.IMConstants.BUY_COUNT;
import static org.jeecg.common.util.constants.WxConstants.SUCCESS;
import static org.jeecg.common.util.constants.WxConstants.XML_TEMPLATE;

/**
 * @author guoyh
 * @ClassName ApiOrderService
 * @Description
 * @since 2020/8/29 01:59
 **/
@Service
@Slf4j
public class ApiOrderService {
    @Resource
    private IDicBeGoodAtService dicBeGoodAtService;
    @Resource
    private IDoctorRegisterOperateService doctorRegisterOperateService;
    @Resource
    private IDoctorRegisterHospitalService doctorRegisterHospitalService;
    @Resource
    private IDoctorConfigService doctorConfigService;
    @Resource
    private WeixinTemplate weixinTemplate;
    @Resource
    private CustomProperties customProperties;
    @Resource
    private IPayOrderService payOrderService;
    @Resource
    private IRegisterPayOrderService registerPayOrderService;
    @Resource
    private IRegisterPatientService registerPatientService;
    @Resource
    private IOrderInfoService orderInfoService;
    @Resource
    private IWxUserinfoService wxUserinfoService;
    @Resource
    private IOrderInfoLogService orderInfoLogService;
    @Resource
    private IDoctorService doctorService;
    @Resource
    private IDoctorWxUserinfoRelationService doctorWxUserinfoRelationService;
    @Resource
    private IDoctorRegisterRecordService doctorRegisterRecordService;
    @Resource
    private IDoctorRegisterService doctorRegisterService;
    @Resource
    private IDicBeGoodAtService iDicBeGoodAtService;
    @Autowired
    private IRoomScordService roomScordService;
    @Autowired
    private IMakeAppointmentInfoService iMakeAppointmentInfoService;
    @Autowired
    private IPatientMedicalRecordsService patientMedicalRecordsService;
    @Autowired
    private IMakeAppointmentService makeAppointmentService;

    public Result<PrePayOrderResponseVo> prePay(PrePayOrderRequestVo request, String openid, String registerRecordId) {

        //【一】判断提交的参数
        if (Objects.isNull(request.getDoctorId()) || Objects.isNull(request.getOrderType())) {
            return ResultMapper.illegalArgument();
        }
        String[] str = request.getDoctorId().split("-");
        String doctorId = str[0];
        //【二】判断支付的类型
        OrderTypeEnum orderType = OrderTypeEnum.getInstance(request.getOrderType());
        log.info("prePay OrderType :" + request.getOrderType());
        if (Objects.isNull(orderType)) {
            return ResultMapper.<PrePayOrderResponseVo>illegalArgument().setMsg("服务类型错误");
        }

        //【三】用户信息
        WxUserinfo wxUserinfo = wxUserinfoService.getByOpenid(openid);

        BigDecimal amount = null;
        long payAmount = 0;
        if (orderType.getCode() == OrderTypeEnum.REGISTER.getCode()) { //** 挂号业务 **//
            //【四】判断是否有挂号未结束的订单
            boolean isDoing = registerPayOrderService.checkDoing(openid, request.getRelationId());  //挂号记录：待支付和待处理的
//            if (isDoing){
//                log.info("有未结束的挂号");
//                return ResultMapper.<PrePayOrderResponseVo>error().setMsg("您有未结束的挂号，请勿重复预约");
//            }
            log.info("是否有重复预约：无");

            //【五】获取支付的金额
            DoctorRegister doctorRegister = doctorRegisterRecordService.getRegisterByRecordId(request.getRelationId());
            if (Objects.isNull(doctorRegister)) {
                log.info(request.getRelationId() + "：未获取到挂号信息");
                return ResultMapper.<PrePayOrderResponseVo>error().setMsg("未获取到挂号信息");
            }
            log.info("doctorRegister：" + doctorRegister);
            DoctorRegisterRecord registerRecord = doctorRegisterRecordService.getById(request.getRelationId());
            log.info("已获取到挂号信息：{}", doctorRegister);
            amount = doctorRegister.getPrice();
            payAmount = AmountUtils.yuanToFen(amount);// 获取支付的金额
            log.info("支付金额：{}", payAmount);
            //获取病人医保卡
            RegisterPatient registerPatient = registerPatientService.getById(registerRecord.getPatientId());
            log.info("registerPatient：" + registerPatient);
            //移除天使妇儿医生、石景山八大处中西医结合医院，全部线下支付
            //if (("1".equals(request.getIsShebao()) && registerPatient != null && registerPatient.getShebaoCard() != null && registerPatient.getShebaoCard().length() > 0 ) || ("1452811085769940994".equals(doctorRegister.getRegisterHospitalId()))|| ("1".equals(doctorRegister.getRegisterHospitalId())) ||(("500001").equals(request.getDoctorId()))){
                log.info("全部修改为线下支付：线下社保");
                registerRecord.setStatus(2);
                if((("500001").equals(request.getDoctorId()))){
                    registerRecord.setRegisterNature("线下支付，加号");
                }else {
                    registerRecord.setRegisterNature("线下支付");
                }

                doctorRegisterRecordService.updateById(registerRecord);
                //【六】创建支付订单记录
                RegisterPayOrder registerpayOrder = registerPayOrderService.initPayOrder(doctorId, request.getRelationId(), wxUserinfo.getId(), 0L, orderType, registerRecordId, registerRecord.getPatientId(), request.getIsShebao());
                try {
                    //处理预约挂号信息推送 短信+微信服务
                    getJsonOperate(registerRecord,doctorRegister);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                //不需要支付，直接执行成功逻辑
                return ResultMapper.<PrePayOrderResponseVo>ok().setData(new PrePayOrderResponseVo()).setMsg("请您到医院窗口付费就诊！");
          //  }
           // log.info("微信支付：微信支付");
            //【六】创建支付订单记录
//            RegisterPayOrder registerpayOrder = registerPayOrderService.initPayOrder(doctorId, request.getRelationId(), wxUserinfo.getId(), payAmount, orderType, registerRecordId, registerRecord.getPatientId());
//            //【七】预支付订单数据
//            try {
//                WCPay wcPay = buildPrePay(openid, payAmount, registerpayOrder.getOrderCode());
//                PrePayOrderResponseVo responseVo = new PrePayOrderResponseVo(true, wcPay);
//                return ResultMapper.<PrePayOrderResponseVo>ok().setData(responseVo);
//            } catch (Exception e) {
//                log.error("微信统一下单接口异常，参数：request:{},openid:{}", JSONUtil.toJsonStr(request), openid);
//                return ResultMapper.<PrePayOrderResponseVo>error().setMsg("微信下单异常");
//            }
        } else {
            String medicalId = request.getMedicalId();
            //【三】获取价格
            log.info("微信支付获取价格：微信支付");
            DoctorConfig doctorConfig = doctorConfigService.getByDoctorId(doctorId, false);
            if (Objects.isNull(doctorConfig)) {
                return ResultMapper.<PrePayOrderResponseVo>error().setMsg("未获取到医生配置");
            }
            amount = OrderTypeEnum.TEXT.equals(orderType) ? doctorConfig.getTextMoney() : doctorConfig.getVideoMoney();
            payAmount = AmountUtils.yuanToFen(amount);// 获取支付的金额

//            //【四】用户信息：判断是否有未结束的订单
//            boolean isDoing = orderInfoService.isDoing(doctorId, wxUserinfo.getId(), orderType.getCode());
//            if (isDoing) {
//                return ResultMapper.<PrePayOrderResponseVo>error().setMsg("您有未结束的订单，请勿重复购买");
//            }

            //【五】创建支付订单记录
            PayOrder payOrder = payOrderService.initPayOrderSP(doctorId, request.getApid(), payAmount, orderType,openid,request.getOrderType(),medicalId);
            if (BigDecimal.ZERO.compareTo(amount) >= 0) {
                //不需要支付，直接执行成功逻辑
                return ResultMapper.<PrePayOrderResponseVo>ok().setData(new PrePayOrderResponseVo());
            }

            //【六】预支付订单数据
            try {
                WCPay wcPay = buildPrePay(openid, payAmount, payOrder.getOrderCode());
                PrePayOrderResponseVo responseVo = new PrePayOrderResponseVo(true, wcPay);

                return ResultMapper.<PrePayOrderResponseVo>ok().setData(responseVo);
            } catch (Exception e) {
                log.error("微信统一下单接口异常，参数：request:{},openid:{}", JSONUtil.toJsonStr(request), openid);
                return ResultMapper.<PrePayOrderResponseVo>error().setMsg("微信下单异常");
            }
        }
    }

    /**
     * 微信公众号支付 —— 支付回调
     *
     * @param body
     * @return
     */
    public String payNotify(String body) throws ParseException {
        String uuid = IdUtil.fastUUID();
        log.info("微信支付回调开始,{}，入参{}", uuid, body);
        //【一】检验签名
        if (!PayUtil.verifySign(body, weixinTemplate.getWeixinPayConfig().getPartnerKey())) {
            log.error("{}微信支付回调返回：签名验证错误", uuid);
            return String.format(XML_TEMPLATE, "FAIL", "签名错误");
        }

        //【二】检验异常数据
        PayNotifyResult payNotifyResult = WxPayUtil.xml2Bean(body);
        if (Objects.isNull(payNotifyResult) || StringUtils.isBlank(payNotifyResult.getOut_trade_no())) {
            log.error("{}微信支付回调返回：异常数据，未解析到订单", uuid);
            return String.format(XML_TEMPLATE, "FAIL", "数据异常");
        }

        //【三】逻辑处理
        Pair<Boolean, String> pair;
        if (StringUtils.equals(payNotifyResult.getResult_code(), SUCCESS)) {
            log.info("支付回调成功");
            pair = paySuccessHandle(payNotifyResult.getOut_trade_no(), payNotifyResult.getTransaction_id(), Long.parseLong(payNotifyResult.getTotal_fee()));
//            getPushInfo(payNotifyResult.getOpenid(), payNotifyResult.getOut_trade_no());
        } else if (StringUtils.equals(payNotifyResult.getResult_code(), "FAIL")) {
            pair = payFailHandle(payNotifyResult.getOut_trade_no(), payNotifyResult.getErr_code_des());
        } else {
            log.error("{}微信支付回调返回：未知的交易状态", uuid);
            pair = Pair.of(false, "未知交易状态");
        }
        if (pair.getLeft()) {
            return String.format(XML_TEMPLATE, "SUCCESS", "OK");
        } else {
            return String.format(XML_TEMPLATE, "FAIL", pair.getRight());
        }
    }

    /**
     * 支付成功的逻辑处理
     *
     * @param orderCode      唯一订单号
     * @param thirdOrderCode 微信支付订单号
     * @param amount         金额
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public Pair<Boolean, String> paySuccessHandle(String orderCode, String thirdOrderCode, Long amount) throws ParseException {
        //【一】订单存在与否的校验
        if (Objects.nonNull(payOrderService.getByOrderCode(orderCode))) { // 订单表
            log.info("原支付订单");
            PayOrder exists = payOrderService.getByOrderCode(orderCode);

            //【二】支付金额的核对
            if (Math.subtractExact(amount, exists.getAmount()) != 0) {
                log.error("金额不符，传入：{},订单：{}", amount, exists.getAmount());
                return Pair.of(false, "金额不符");
            }

            //【三】已处理过
            if (!Objects.equals(exists.getStatus(), PayOrderStatusEnum.WAIT_PAING.getCode())) {
                log.info("该订单状态非待支付，无需处理{}", orderCode);
                return Pair.of(true, null);
            }

            //【四】更新支付订单
            exists.setEndPayTime(new Date());
            exists.setStatus(PayOrderStatusEnum.SUCCESS.getCode());
            exists.setThirdOrderCode(thirdOrderCode);
            payOrderService.updateById(exists);

            //【六】保存订单数据
//            OrderInfo orderInfo = orderInfoService.initOrder(exists);

            //【七】添加订单操作日志
            orderInfoLogService.addLog(exists.getRelationId(), OrderInfoLogTypeEnum.CREATE, "视频");

            //shopType = 2 视频问诊
            if (exists.getShopType() == 2) {
                //获取病例信息
                PatientMedicalRecords patientMedicalRecords = patientMedicalRecordsService.getById(exists.getMedicalId());
                if (Objects.isNull(patientMedicalRecords)) {
                    log.error("获取患者信息失败,{}", orderCode);
                    return Pair.of(true, null);
                }
                patientMedicalRecords.getPhone();
                patientMedicalRecords.getDoctorId();
                //更新视频预约状态 为已完成支付
                MakeAppointment makeAppointment = makeAppointmentService.getById(exists.getRelationId());
                makeAppointment.setId(exists.getRelationId());
                makeAppointment.setStatus("2");
                makeAppointment.setSurplus(makeAppointment.getSurplus()-1);
                makeAppointmentService.updateById(makeAppointment);
                Doctor doctor = doctorService.getById(exists.getDoctorId());
                try {
                    DySmsHelper.sendSms(doctor.getMobile(), new JSONObject(), DySmsEnum.NEW_ORDER);
                    //微信消息通知
                } catch (Exception e) {
                    log.error("发送短信失败");
                }
                getPushInfo(exists.getOpenid(),doctor.getId(),patientMedicalRecords.getId(),exists.getRelationId());
                return Pair.of(true, null);
            } else {
                //【八】【问诊】发送短信
                WxUserinfo wxUserinfo = wxUserinfoService.getById(exists.getWxUserinfoId());
                if (Objects.isNull(wxUserinfo)) {
                    log.error("获取患者信息失败,{}", orderCode);
                    return Pair.of(true, null);
                }
                DoctorWxUserinfoRelation doctorWxUserinfoRelation = doctorWxUserinfoRelationService.getByDoctorAndOpenid(exists.getDoctorId(), wxUserinfo.getOpenid());
                if (Objects.isNull(doctorWxUserinfoRelation)) {
                    log.error("获取医患关系失败,{}", orderCode);
                }

                OrderTypeEnum orderTypeEnum = OrderTypeEnum.getInstance(exists.getShopType());
                if (OrderTypeEnum.TEXT.equals(orderTypeEnum)) {
                    doctorWxUserinfoRelation.setTextNumber(BUY_COUNT);
                } else if (OrderTypeEnum.VIDEO.equals(orderTypeEnum)) {
                    doctorWxUserinfoRelation.setVideoNumber(1);
                }
                doctorWxUserinfoRelationService.updateById(doctorWxUserinfoRelation);
                try {
                    Doctor doctor = doctorService.getById(doctorWxUserinfoRelation.getDoctorId());
                    DySmsHelper.sendSms(doctor.getMobile(), new JSONObject(), DySmsEnum.NEW_ORDER);
                } catch (Exception e) {
                    log.error("发送短信失败");
                }

                return Pair.of(true, null);
            }

        } else if (Objects.nonNull(registerPayOrderService.getByOrderCode(orderCode))) {  // 挂号订单表
            log.info("挂号订单");
            RegisterPayOrder exists = registerPayOrderService.getByOrderCode(orderCode);

            //【二】支付金额的核对
            if (Math.subtractExact(amount, exists.getAmount()) != 0) {
                log.error("金额不符，传入：{},订单：{}", amount, exists.getAmount());
                return Pair.of(false, "金额不符");
            }
            //获取待支付订单，并伪删除订单
            LambdaQueryWrapper<RegisterPayOrder> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(RegisterPayOrder::getPatientId, exists.getPatientId());
            queryWrapper.eq(RegisterPayOrder::getRelationId, exists.getRelationId());
            queryWrapper.eq(RegisterPayOrder::getInvalid, 0);
            List<RegisterPayOrder> order = registerPayOrderService.list(queryWrapper);
            if (order.size() > 0) {
                for (RegisterPayOrder d : order) {
                    d.setInvalid("1");
                    registerPayOrderService.updateById(d);
                }

            }
            //【三】已处理过
            if (!Objects.equals(exists.getStatus(), PayOrderStatusEnum.WAIT_PAING.getCode())) {
                log.info("该订单状态非待支付，无需处理{}", orderCode);
                return Pair.of(true, null);
            }

            //【四】更新支付订单
            exists.setEndPayTime(new Date());
            exists.setStatus(PayOrderStatusEnum.SUCCESS.getCode());
            exists.setThirdOrderCode(thirdOrderCode);
            registerPayOrderService.updateById(exists);


            //【五】【挂号记录表】更改挂号记录表状态
            DoctorRegisterRecord doctorRegisterRecord = doctorRegisterRecordService.getById(exists.getRelationId());
            doctorRegisterRecord.setStatus(1); //待处理（已支付）
            doctorRegisterRecordService.updateById(doctorRegisterRecord);

            //【六】【挂号表】余号自减
            DoctorRegister doctorRegister = doctorRegisterService.getById(doctorRegisterRecord.getDoctorRegisterId());
            log.info("挂号表信息-查询：{}", doctorRegister);
            doctorRegister.setSurplusNum(doctorRegister.getSurplusNum() - 1);
            log.info("挂号表信息-自减：{}", doctorRegister);
            doctorRegisterService.updateById(doctorRegister);

            //【七】通知运营人员办事
            this.getJsonOperate(doctorRegisterRecord, doctorRegister);

            return Pair.of(true, null);
        } else {
            return Pair.of(false, "不存在的订单");
        }
    }

    /**
     * 通知运营人员
     *
     * @param doctorRegisterRecord 此次挂号对应的挂号记录信息
     * @param doctorRegister       此次挂号对应的挂号信息
     */
    public String getJsonOperate(DoctorRegisterRecord doctorRegisterRecord, DoctorRegister doctorRegister) throws ParseException {
        //运营人员列表
        List<DoctorRegisterOperate> operateList = doctorRegisterOperateService.operateList();
        if (operateList.size() == 0) {
            return null;
        }

        //处理挂号日期
        Date visitTime = new SimpleDateFormat("yyyy-MM-dd").parse(doctorRegister.getVisitTime());
        String visitTimeStr = new SimpleDateFormat("yyyy年MM月dd日").format(visitTime);
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        String startTime = sdf.format(doctorRegisterRecord.getStartTime());
        String endTime = sdf.format(doctorRegisterRecord.getEndTime());
        //组织医院科室信息
        String depart = "";
        String departmentName = dicBeGoodAtService.getById(doctorRegister.getDepartment()).getName(); //科室名称
        String departEnd = departmentName.substring(departmentName.length() - 1); //“xxx科室”的最后一个字
        if (departEnd.equals("科")) {
            depart = departmentName.substring(0, departmentName.length() - 1);  //去除"xxx科室"的最后一个字
        } else {
            depart = departmentName;
        }
        //医院名称
        DoctorRegisterHospital hosipal = doctorRegisterHospitalService.getById(doctorRegister.getRegisterHospitalId());
        String hospitalName = hosipal.getName();
        //医生信息
        Doctor doctor = doctorService.getById(doctorRegister.getDoctorId());
        //患者信息
        RegisterPatient registerPatient = registerPatientService.getById(doctorRegisterRecord.getPatientId());

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name_1", registerPatient.getName());  //患者姓名
        jsonObject.put("hospital_ment", hospitalName + " " + departmentName); //xxx医院xxx科
        jsonObject.put("name_title", doctor.getName() + "(" + doctor.getTitle() + ")");  //xx医生xx职位
        jsonObject.put("date_part", visitTimeStr + " " + startTime +"~"+ endTime  + " " + doctorRegister.getVisitPart());   //xx时间xx号
        jsonObject.put("num", doctorRegisterRecord.getVisitNum());
        jsonObject.put("patient_p", "电话：" + registerPatient.getMobile());
        log.info("运营消息json：{}", jsonObject);

        //自动处理挂号
        DoctorRegisterRecordSysListVo requestVo = new DoctorRegisterRecordSysListVo();
        requestVo.setDepartmentName(departmentName);
        requestVo.setDoctorName(doctor.getName());
        requestVo.setFailReason("");
        requestVo.setHospitalAddress(hosipal.getAddress());
        requestVo.setHospitalName(hosipal.getName());
        requestVo.setHospitalPhone(hosipal.getPhone());
        requestVo.setId(doctorRegisterRecord.getId());
        requestVo.setOpenid(doctorRegisterRecord.getOpenid());
        requestVo.setPatientMobile(registerPatient.getMobile());
        requestVo.setPatientName(registerPatient.getName());
        requestVo.setPrice(doctorRegister.getPrice());
        requestVo.setRegisterTime(doctorRegisterRecord.getRegisterTime());
        requestVo.setStatus(RegisterEnum.SUCCESS.getCode());
        requestVo.setTitle(doctor.getTitle());
        requestVo.setType(doctorRegister.getType());
        requestVo.setVisitNum(doctorRegisterRecord.getVisitNum());
        requestVo.setVisitPart(doctorRegister.getVisitPart());
        requestVo.setVisitTime(doctorRegister.getVisitTime());
        requestVo.setStartTime(startTime);
        requestVo.setEndTime(endTime);
        requestVo.setId(doctorRegisterRecord.getOpenid());
        requestVo.setDoctorRegisterId(doctorRegisterRecord.getId());
        examine(requestVo);

        try {
            //通知运营人员
            for (DoctorRegisterOperate doctorRegisterOperate : operateList) {
                DySendMsg.sendSms(doctorRegisterOperate.getPhone(), jsonObject, DySmsEnum.REGISTER_OPERATE_NOTICE);
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 支付失败的逻辑处理
     *
     * @param orderCode
     * @param reason
     * @return
     */
    public Pair<Boolean, String> payFailHandle(String orderCode, String reason) {
        PayOrder exists = payOrderService.getByOrderCode(orderCode);
        if (Objects.isNull(exists)) {
            return Pair.of(false, "不存在的订单");
        }
        exists.setEndPayTime(new Date());
        exists.setStatus(PayOrderStatusEnum.FAIL.getCode());
        payOrderService.updateById(exists);
        return Pair.of(true, null);
    }

    /**
     * 预支付订单
     *
     * @param openid
     * @param amount
     * @param orderCode
     * @return
     * @throws WeixinException
     */
    private WCPay buildPrePay(String openid, Long amount, String orderCode) throws WeixinException {
        UnifiedOrder unifiedOrder = new UnifiedOrder();
        String appid = weixinTemplate.getWeixinConfig().getAppid();
        String partnerKey = weixinTemplate.getWeixinPayConfig().getPartnerKey();
        String nonceStr = IdUtil.createSnowflake(1, 1).nextIdStr();
        unifiedOrder.setAppid(appid);
        unifiedOrder.setMch_id(weixinTemplate.getWeixinPayConfig().getPartnerId());
        unifiedOrder.setNonce_str(nonceStr);
        unifiedOrder.setOut_trade_no(orderCode);
        unifiedOrder.setTotal_fee(amount.toString());
        unifiedOrder.setNotify_url(customProperties.getH5ApiDomain().concat("/notify/payNotify"));
        unifiedOrder.setTrade_type("JSAPI");
        unifiedOrder.setOpenid(openid);
        unifiedOrder.setBody("在线咨询");
        unifiedOrder.setSpbill_create_ip("127.0.0.1");
        Map<String, String> map = unifiedOrder.toMap();
        String sign = SignUtil.getSign(map, partnerKey);
        unifiedOrder.setSign(sign);
        log.info("微信统一下单接口，入参：{}", unifiedOrder.toXML());
        UnifiedOrderResult result = weixinTemplate.pay().payUnifiedOrder(unifiedOrder);
        log.info("微信统一下单接口，返回：{}", JSONUtil.toJsonStr(result));
        if (!StringUtils.equals(SUCCESS, result.getReturn_code()) || !StringUtils.equals(SUCCESS, result.getResult_code())) {
            throw new RuntimeException("微信统一下单异常");
        }
        return PayUtil.getBrandWCPayRequest(appid, result.getPrepay_id(), partnerKey);
    }

    //进行听订单
    public List<OrderInfo> order(String doctorId, String wxUserId) {
        OrderInfo info = new OrderInfo();
        info.setWxUserinfoId(wxUserId);
        info.setDoctorId(doctorId);
        info.setStatus(OrderStatusEnum.DOING.getCode());
        info.setShopType(OrderTypeEnum.TEXT.getCode());
        return orderInfoService.list(Wrappers.lambdaQuery(info));
    }

    public void getPushInfo(String openId, String doctorId, String medicalId,String relationId) {

        try {
            Doctor doctorInfo = doctorService.getById(doctorId);
            WxUserinfo userInfo = wxUserinfoService.getByOpenid(openId);
            DicBeGoodAt depart = iDicBeGoodAtService.getById(doctorInfo.getDepartment());

            Date d = new Date();
            final long l = System.currentTimeMillis();
            final int i = (int) (l % 100000);
            String url = null;

            RoomScord roomScord = new RoomScord();
            roomScord.setDoctorId(doctorInfo.getId());
            roomScord.setDate(new Date());
            roomScord.setRoomNumber(i);
            roomScord.setDoctorName(doctorInfo.getName());
            roomScord.setPatientId(openId);
            roomScord.setPatientName(userInfo.getNickname());
            roomScord.setMedicalId(medicalId);
            roomScord.setStatus("已发送");

            log.info("openId666：{}", openId);
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String dateNowStr = sdf.format(date);
            Date today = sdf.parse(dateNowStr);
            log.info("new Date()：{}", date.getYear() - (date.getMonth() + 1) - date.getDate());
//            MakeAppointmentInfo info = iMakeAppointmentInfoService.getOne(Wrappers.lambdaQuery(MakeAppointmentInfo.class).eq(MakeAppointmentInfo::getOpenid, openId).eq(MakeAppointmentInfo::getDoctorId, doctorInfo.getId()).eq(MakeAppointmentInfo::getDate, today).last(" limit 1"));
//            PatientMedicalRecords patientMedicalRecords =  patientMedicalRecordsService.getById(medicalId);
            MakeAppointment makeAppointment = makeAppointmentService.getById(relationId);
            if (CommonUtils.IS_ZS) {
                url = "https://zzt.weixin.dyzh120.com/invite-govNew/";
            }
            SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm");
            String startTime = sdf1.format(makeAppointment.getStartTime());
            Date start = sdf1.parse(startTime);
            String endTime = sdf1.format(makeAppointment.getEndTime());
            Date end = sdf1.parse(endTime);
            log.info("info.getStartTime()~info.getEndTime()：{}", start + "~" + end);
            WeixinUtil.push(openId, userInfo.getNickname(), depart.getName(), doctorInfo.getName(), sdf.format(makeAppointment.getDate() ) + " " + makeAppointment.getVartPart(), i + "（视频房间号）", "咨询医助微信，请查看详情，扫二维码加入", url);
            //新增房间记录
            roomScordService.save(roomScord);
        } catch (ParseException e) {
            e.printStackTrace();
        }


        //        if(add(roomScord)){
//            //测试站
////            url = "https://test.weixin.dyzh120.com/invite-govNew/"+doctorInfo.getId();
//            //正式站
//             url = "https://weixin.dyzh120.com/invite-govNew/"+doctorInfo.getId();
//            WeixinUtil.push(openId,  userInfo.getNickname(), depart.getName(), doctorInfo.getName(), new SimpleDateFormat("yyyy-MM-dd").format(new Date()),i+"","咨询医助微信，请查看详情，扫二维码加入",url);
//        }
    }

    public Boolean add(RoomScord roomScord) {
        RoomScord one = roomScordService.getOne(Wrappers.lambdaQuery(RoomScord.class).eq(RoomScord::getPatientId, roomScord.getPatientId()).eq(RoomScord::getDate, roomScord.getDate()));
        if (ObjectUtil.isNull(one)) {
            roomScordService.save(roomScord);
            return true;
        }
        return false;
    }


    /**
     * 挂号单审核操作 修改未自动处理
     */
    public void examine(DoctorRegisterRecordSysListVo requestVo) {
        log.info("------------------------挂号单审核操作 修改未自动处理-------------------------------------" + requestVo);
        //【一】发送短信
        try {
            JSONObject jsonObject = new JSONObject();
            //组织医院科室信息
//            String depart = "";
//            String departEnd = requestVo.getDepartmentName().substring(requestVo.getDepartmentName().length() - 1);
//            if (departEnd.equals("科")) {
//                depart = requestVo.getDepartmentName().substring(0, requestVo.getDepartmentName().length() - 1);
//            } else {
//                depart = requestVo.getDepartmentName();
//            }

            //处理日期
            Date visitTime = new SimpleDateFormat("yyyy-MM-dd").parse(requestVo.getVisitTime());
            String visitTimeStr = new SimpleDateFormat("yyyy年MM月dd日").format(visitTime);
            String url = "";
            if (requestVo.getStatus() == RegisterEnum.SUCCESS.getCode()) {  //挂号成功
                jsonObject.put("name_1", requestVo.getPatientName());

                jsonObject.put("hospital_ment", requestVo.getHospitalName() + " " + requestVo.getDepartmentName()); //xx医院xx科室
                jsonObject.put("name_title", requestVo.getDoctorName() + "(" + requestVo.getTitle().trim() + ")");  //xx医生xx职位
                jsonObject.put("date_part", visitTimeStr + " " + requestVo.getStartTime() +"~"+ requestVo.getEndTime() + " "+ requestVo.getVisitPart());  //xx日期xx时间段
                jsonObject.put("num", "以窗口序号为主！");  //就诊序号
                jsonObject.put("hospital_2", requestVo.getHospitalAddress());  //医院地址
                jsonObject.put("phone_1", requestVo.getHospitalPhone());   //医院联系电话
                if (CommonUtils.IS_ZS) {
                    url = "https://zzt.weixin.dyzh120.com/invite-govNew/";
                }
                WeixinUtil.pushRegisterSuccess(requestVo.getId(), requestVo.getPatientName(), requestVo.getHospitalName() + " " + requestVo.getDepartmentName(), requestVo.getDoctorName() + "(" + requestVo.getTitle() + ")", visitTimeStr + " " + requestVo.getVisitPart(), requestVo.getHospitalAddress(), "大医智慧", url);

            } else if (requestVo.getStatus() == RegisterEnum.FAIL.getCode()) {  //挂号失败
                jsonObject.put("name", requestVo.getPatientName());
                jsonObject.put("hospital_department", requestVo.getHospitalName() + " " + requestVo.getDepartmentName());
                jsonObject.put("doctor", requestVo.getDoctorName().trim());
                jsonObject.put("date_part", visitTimeStr + " " + requestVo.getVisitPart());
                jsonObject.put("phone_2", requestVo.getHospitalPhone());
                if (CommonUtils.IS_ZS){
                    url = "https://zzt.weixin.dyzh120.com/invite-govNew/";
                }
                WeixinUtil.pushRegisterFalse(requestVo.getId(), requestVo.getPatientName(), requestVo.getHospitalName() + " " + requestVo.getDepartmentName(), requestVo.getDoctorName() + "(" + requestVo.getTitle() + ")", visitTimeStr + " " + requestVo.getVisitPart(), requestVo.getHospitalAddress(), "大医智慧", url);
            }

            log.info("短信数据\n：{}", String.valueOf(jsonObject));
            boolean sendRes = false;
            try {
                if (requestVo.getStatus() == RegisterEnum.SUCCESS.getCode()) {     // 挂号成功
                    sendRes = DySendMsg.sendSms(requestVo.getPatientMobile(), jsonObject, DySmsEnum.REGISTER_NOTICE);
                } else if (requestVo.getStatus() == RegisterEnum.FAIL.getCode()) {  // 挂号失败
                    sendRes = DySendMsg.sendSms(requestVo.getPatientMobile(), jsonObject, DySmsEnum.REGISTER_FAIL_NOTICE);
                }

                //【二】更新挂号状态
                DoctorRegisterRecord doctorRegisterRecord = doctorRegisterRecordService.getById(requestVo.getDoctorRegisterId());
                doctorRegisterRecord.setStatus(RegisterEnum.SUCCESS.getCode());
                doctorRegisterRecord.setExamineTime(new Date());
                doctorRegisterRecord.setFailReason(requestVo.getFailReason());
                boolean recordRes = doctorRegisterRecordService.updateById(doctorRegisterRecord);
                if (!recordRes) {
                    new Exception();
                }
            } catch (ClientException e) {
                e.printStackTrace();
            }

//            if(sendRes){
//                //【二】更新挂号状态
//                DoctorRegisterRecord doctorRegisterRecord = doctorRegisterRecordService.getById(requestVo.getId());
//                doctorRegisterRecord.setStatus(requestVo.getStatus());
//                doctorRegisterRecord.setExamineTime(new Date());
//                doctorRegisterRecord.setFailReason(requestVo.getFailReason());
//                boolean recordRes = doctorRegisterRecordService.updateById(doctorRegisterRecord);
//                if(!recordRes){
//                    return org.jeecg.common.api.vo.Result.error("处理失败，请稍后重试！");
//                }
//                return org.jeecg.common.api.vo.Result.ok("处理成功！");
//            }else{
//                return org.jeecg.common.api.vo.Result.error("短信发送失败，请稍后重试！");
//            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

}
